package com.atguigu.gmall.activity.service.impl;

import com.alibaba.nacos.common.utils.StringUtils;
import com.atguigu.gmall.activity.mapper.SeckillGoodsMapper;
import com.atguigu.gmall.activity.service.SeckillGoodsService;
import com.atguigu.gmall.activity.util.CacheHelper;
import com.atguigu.gmall.common.constant.MqConst;
import com.atguigu.gmall.common.constant.RedisConst;
import com.atguigu.gmall.common.result.Result;
import com.atguigu.gmall.common.result.ResultCodeEnum;
import com.atguigu.gmall.common.service.RabbitService;
import com.atguigu.gmall.model.activity.OrderRecode;
import com.atguigu.gmall.model.activity.SeckillGoods;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisCommand;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@Service
@SuppressWarnings("all")
public class SeckillGoodsServiceImpl implements SeckillGoodsService {

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private RabbitService rabbitService;

    @Autowired
    private SeckillGoodsMapper seckillGoodsMapper;

    /**
     * 查询秒杀商品列表
     * @return
     */
    @Override
    public List<SeckillGoods> findAll() {


        List<SeckillGoods> seckillGoodsList = redisTemplate.opsForHash().values(RedisConst.SECKILL_GOODS);

        return seckillGoodsList;
    }

    /**
     * 查询秒杀商品详情
     * @param skuId
     * @return
     */
    @Override
    public SeckillGoods getSeckillGoods(Long skuId) {

        SeckillGoods seckillGoods = (SeckillGoods) redisTemplate.boundHashOps(RedisConst.SECKILL_GOODS).get(skuId.toString());
        return seckillGoods;
    }

    /**
     * 监听秒杀下单
     * @param userId
     * @param skuId
     */
    @Override
    public void seckillOrder(String userId, Long skuId) {

        //判断状态位
        String state = (String) CacheHelper.get(skuId.toString());
        if(!"1".equals(state)){
            return;
        }

        //判断是否下过单--购买量限制 1        setnx
        String userKey=RedisConst.SECKILL_USER+userId+skuId;
        //查询是否存在购物记录
        Boolean isExit = redisTemplate.opsForValue().setIfAbsent(userKey, skuId.toString(), RedisConst.SECKILL__TIMEOUT, TimeUnit.SECONDS);
        //判断
        if(!isExit){
            return;
        }


        //校验商品库存
        String stockKey=RedisConst.SECKILL_STOCK_PREFIX+skuId;
        //获取抢购商品id
        String goodsId = (String) redisTemplate.opsForList().rightPop(stockKey);
        //判断
        if(StringUtils.isEmpty(goodsId)){
            //同步状态--商品已售罄
            redisTemplate.convertAndSend("seckillpush",skuId+":0");
            return ;
        }

        //生成订单，存储到redis--临时订单
        OrderRecode orderRecode=new OrderRecode();
        orderRecode.setUserId(userId);
        SeckillGoods seckillGoods = getSeckillGoods(skuId);
        orderRecode.setSeckillGoods(seckillGoods);
        orderRecode.setNum(1);
        orderRecode.setOrderStr(UUID.randomUUID().toString().replaceAll("-",""));

        //存储临时订单
        redisTemplate.boundHashOps(RedisConst.SECKILL_ORDERS).put(userId,orderRecode);

        //更新库存 redis  mysql --mq

        rabbitService.sendMessaged(
                MqConst.EXCHANGE_DIRECT_SECKILL_STOCK,
                MqConst.ROUTING_SECKILL_STOCK,
                goodsId
        );


    }

    /**
     * 更新库存
     * @param goodsId
     */
    @Override
    public void updateStock(String goodsId) {

        //获取现有库存
        String stockKey=RedisConst.SECKILL_STOCK_PREFIX+goodsId;
        Long count = redisTemplate.boundListOps(stockKey).size();
        //查询goodsId对应的商品详情
        SeckillGoods seckillGoods = getSeckillGoods(Long.valueOf(goodsId));
        //更新库存量
        seckillGoods.setStockCount(count.intValue());
        if(count%2==0){
            //更新redis库存量
            redisTemplate.boundHashOps(RedisConst.SECKILL_GOODS).put(goodsId,seckillGoods);
            //更新mysql中SeckillGoods
            this.seckillGoodsMapper.updateById(seckillGoods);
        }




    }

    /**
     * 检查秒杀状态
     * @param userId
     * @param skuId
     * @return
     */
    @Override
    public Result checkOrder(String userId, String skuId) {

        //获取用户抢购记录
        String userKey=RedisConst.SECKILL_USER+userId+skuId;
        Boolean flag = redisTemplate.hasKey(userKey);
        //判断
        if(flag){
            //判断是否存在临时订单
            Boolean isExit = redisTemplate.boundHashOps(RedisConst.SECKILL_ORDERS).hasKey(userId);
            //判断
            if(isExit){
                OrderRecode orderRecode = (OrderRecode) redisTemplate.boundHashOps(RedisConst.SECKILL_ORDERS).get(userId);

                return Result.build(orderRecode, ResultCodeEnum.SECKILL_SUCCESS);
            }
            //判断是否有持久订单---支付后会删除临时订单，保存为持久订单到redis
            //存储持久订单的key为： SECKILL_ORDERS_USERS
            Boolean aBoolean = redisTemplate.boundHashOps(RedisConst.SECKILL_ORDERS_USERS).hasKey(userId);
            //判断
            if(aBoolean){

                return Result.build(null,ResultCodeEnum.SECKILL_ORDER_SUCCESS);
            }



        }

        //没有用户抢购记录
        //获取状态位
        String state = (String) CacheHelper.get(skuId);
        //已售罄
        if("0".equals(state)){
            return Result.build(null,ResultCodeEnum.SECKILL_FINISH);
        }


        return Result.build(null,ResultCodeEnum.SECKILL_RUN);
    }
}
